#coding:utf8
from rest_framework import serializers
from .models import User, Address
from django_redis import get_redis_connection
from rest_framework_jwt.settings import api_settings

from django.core.mail import send_mail
from django.conf import settings
# ModelSerializer       -- 有关联的模型 , 数据入库 直接调用 create方法不用我们自己手动实现
# Serializer
class CreateUserSerializer(serializers.ModelSerializer):


    #用户名,密码,密码2,手机号,短信验证码, 是否同意协议

    # 自动生成的字段 和需求不一致
    # read_only 只读
    # write_only 只写  在序列化(模型-->JSON)不能用
    password2 = serializers.CharField(label='确认密码',write_only=True,allow_null=False,allow_blank=False)
    sms_code = serializers.CharField(label='短信验证码', max_length=6, min_length=6, allow_null=False, allow_blank=False,
                                     write_only=True)
    allow = serializers.CharField(label='是否同意协议', allow_null=False, allow_blank=False, write_only=True)


    token = serializers.CharField(label='登录状态token',read_only=True)
    class Meta:
        model = User
        fields = ['id','username','password','mobile','password2','sms_code','allow','token']
        extra_kwargs = {
            'username': {
                'min_length': 5,
                'max_length': 20,
                'error_messages': {
                    'min_length': '仅允许5-20个字符的用户名',
                    'max_length': '仅允许5-20个字符的用户名',
                }
            },
            'password': {
                'write_only': True,
                'min_length': 8,
                'max_length': 20,
                'error_messages': {
                    'min_length': '仅允许8-20个字符的密码',
                    'max_length': '仅允许8-20个字符的密码',
                }
            }
        }


    # 用户名,密码,密码2,手机号,短信验证码, 是否同意协议

    # 单个字段校验
    # 手机号,是否同意协议
    def validate_mobile(self,value):
        import re
        if not re.match(r'1[3-9]\d{9}',value):
            raise serializers.ValidationError('手机号错误')
        return value

    def validate_allow(self,value):

        if value != 'true':
            return serializers.ValidationError('您暂未同意协议')

        return value

    #多个字段校验

    def validate(self, attrs):

        # 1判断用户的密码是否一致
        password = attrs.get('password')
        password2 = attrs.get('password2')
        if password != password2:
            raise serializers.ValidationError('密码不一致')

        # 2.判断短信校验码

        # 链接reids
        redis_conn = get_redis_connection('code')
        # 获取短信验证码, 判断是否存在
        redis_code = redis_conn.get('sms_%s'%attrs.get('mobile'))

        if redis_code is None:
            raise serializers.ValidationError('短信验证码过期')

        # redis是数据是bytes类型
        # 比对
        if redis_code.decode() != attrs.get('sms_code'):
            raise serializers.ValidationError('验证码错误')


        return attrs


    def create(self, validated_data):

        del validated_data['password2']
        del validated_data['sms_code']
        del validated_data['allow']

        user = super().create(validated_data)

        user.set_password(validated_data['password'])
        user.save()

        # 补充生成记录登录状态的token
        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)


        return user



class UserCenterInfoSerializer(serializers.ModelSerializer):

    class Meta:

        model = User
        fields = ('id', 'username', 'mobile', 'email', 'email_active')


class EmailSerializer(serializers.ModelSerializer):

    class Meta:

        model = User
        fields = ('id', 'email')
        extra_kwargs = {
            'email':{'required':True}
        }

    def update(self, instance, validated_data):

        # 获取邮箱
        email = validated_data.get('email')
        # 保存数据
        instance.email = email
        instance.save()

        # 发送激活邮件


        # subject = '美多商城注册邮件'
        # message = ''
        # from_email = settings.EMAIL_FROM
        # recipient_list = [email]
        # html_message = '<h1>激活邮件</h1>'
        # send_mail(subject=subject,
        #           message=message,
        #           from_email=from_email,
        #           recipient_list=recipient_list,
        #           html_message=html_message)


        # 激活链接如何实现
        # 应该包含什么信息
        # 用户的邮箱和id进行加密

        verify_url = instance.generic_email_token(email)
        print(verify_url)
        # subject = "美多商城邮箱验证"
        # html_message = '<p>尊敬的用户您好！</p>' \
        #                '<p>感谢您使用美多商城。</p>' \
        #                '<p>您的邮箱为：%s 。请点击此链接激活您的邮箱：</p>' \
        #                '<p><a href="%s">%s<a></p>' % (email, verify_url, verify_url)
        #
        # send_mail(subject, "", settings.EMAIL_FROM, [email], html_message=html_message)

        from celery_tasks.email.tasks import send_verify_email

        send_verify_email.delay(email,verify_url)

        return  instance


class AddressSerializer(serializers.ModelSerializer):

    province = serializers.StringRelatedField(read_only=True)
    city = serializers.StringRelatedField(read_only=True)
    district = serializers.StringRelatedField(read_only=True)
    province_id = serializers.IntegerField(label='省ID', required=True)
    city_id = serializers.IntegerField(label='市ID', required=True)
    district_id = serializers.IntegerField(label='区ID', required=True)
    mobile = serializers.RegexField(label='手机号', regex=r'^1[3-9]\d{9}$')

    class Meta:
        model = Address
        exclude = ('user', 'is_deleted', 'create_time', 'update_time')


    def create(self, validated_data):
        #Address模型类中有user属性,将user对象添加到模型类的创建参数中
        validated_data['user'] = self.context['request'].user
        return super().create(validated_data)

class AddressTitleSerializer(serializers.ModelSerializer):
    """
    地址标题
    """
    class Meta:
        model = Address
        fields = ('title',)